package de.karlNet.sshTray.gui;

import javax.swing.JFrame;
import java.awt.BorderLayout;
import java.awt.MenuItem;
import java.awt.PopupMenu;

import javax.swing.JPanel;
import java.awt.GridBagLayout;
import javax.swing.JLabel;
import java.awt.GridBagConstraints;
import javax.swing.JTextField;
import java.awt.Insets;
import javax.swing.JButton;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;

import de.karlNet.sshTray.controller.TypeController;
import de.karlNet.sshTray.datasources.IChangeListener;
import de.karlNet.sshTray.datasources.IDataSource;
import de.karlNet.sshTray.gui.tableModels.ConnectionsTableModel;
import de.karlNet.sshTray.model.Connection;
import de.karlNet.sshTray.model.Type;

import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JComboBox;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class ManageConnectionsWindow extends JFrame implements IChangeListener {
	/**
	 * 
	 */
	private final JComboBox typeCombobox;
	private static final long serialVersionUID = 1L;
	private JTextField txtTitle;
	private JTextField txtHostname;
	private JTextField txtUsername;
	private JTable table;
	private ConnectionsTableModel connectionsTableModel;
	private JTextField txtId;
	
	@Autowired
	private IDataSource dataSource;
	
	@Autowired
	private TypeController typeController;

	
	
	public ManageConnectionsWindow() {
		
		setTitle("Manage Connections");
		setSize(400, 600);
		setLocationRelativeTo(null);
		getContentPane().setLayout(new BorderLayout(0, 0));
		typeCombobox = new JComboBox();
		JPanel panel1 = new JPanel();
		getContentPane().add(panel1, BorderLayout.CENTER);
		GridBagLayout gbl_panel1 = new GridBagLayout();
		gbl_panel1.columnWidths = new int[] { 0, 0 };
		gbl_panel1.rowHeights = new int[] { 0, 0, 0 };
		gbl_panel1.columnWeights = new double[] { 1.0, Double.MIN_VALUE };
		gbl_panel1.rowWeights = new double[] { 0.0, 1.0, Double.MIN_VALUE };
		panel1.setLayout(gbl_panel1);

		final JPanel panel = new JPanel();
		table = new JTable(connectionsTableModel = new ConnectionsTableModel());
		final JPopupMenu popupMenu = new JPopupMenu();
		JMenuItem create = new JMenuItem("Create");
		create.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				panel.setVisible(true);
			}
		});
		JMenuItem delete = new JMenuItem("Delete");
		delete.addActionListener(new ActionListener() {

			public void actionPerformed(ActionEvent arg0) {
				int selRow = table.getSelectedRow();
				if (selRow < 0) {
					return;
				}
				dataSource.deleteConnection(connectionsTableModel
						.getConnectionAt(selRow));
			}
		});
		JMenuItem edit = new JMenuItem("edit");

		JMenuItem connect = new JMenuItem("Connect...");
		connect.addActionListener(new ActionListener() {

			public void actionPerformed(ActionEvent arg0) {
				int selRow = table.getSelectedRow();
				if (selRow < 0) {
					return;
				}
				connectionsTableModel.getConnectionAt(selRow).connect();
			}
		});
		JMenuItem moveUp = new JMenuItem("Move Up");
		moveUp.addActionListener(new ActionListener() {

			public void actionPerformed(ActionEvent arg0) {
				int selRow = table.getSelectedRow();
				if (selRow < 0) {
					return;
				}
				dataSource.moveConnectionUp(connectionsTableModel
						.getConnectionAt(selRow));
			}
		});
		JMenuItem moveDown = new JMenuItem("Move down");
		moveDown.addActionListener(new ActionListener() {

			public void actionPerformed(ActionEvent arg0) {
				int selRow = table.getSelectedRow();
				if (selRow < 0) {
					return;
				}
				dataSource.moveConnectionDown(connectionsTableModel
						.getConnectionAt(selRow));
			}
		});

		popupMenu.add(create);
		popupMenu.add(delete);
		popupMenu.add(edit);
		popupMenu.add(connect);
		popupMenu.add(moveUp);
		popupMenu.add(moveDown);
		table.addMouseListener(new MouseAdapter() {
			public void mousePressed(MouseEvent e) {
				showPopup(e);
			}

			public void mouseReleased(MouseEvent e) {
				showPopup(e);
			}

			private void showPopup(MouseEvent e) {
				if (e.isPopupTrigger()) {
					popupMenu.show(e.getComponent(), e.getX(), e.getY());
				}
			}

		});

		GridBagConstraints gbc_table = new GridBagConstraints();
		gbc_table.fill = GridBagConstraints.BOTH;
		gbc_table.gridx = 0;
		gbc_table.gridy = 1;
		panel1.add(new JScrollPane(table), gbc_table);

		getContentPane().add(panel, BorderLayout.NORTH);
		GridBagLayout gbl_panel = new GridBagLayout();
		gbl_panel.columnWidths = new int[] { 0, 0, 0 };
		gbl_panel.rowHeights = new int[] { 0, 0, 0, 0, 0, 0, 0 };
		gbl_panel.columnWeights = new double[] { 0.0, 1.0, Double.MIN_VALUE };
		gbl_panel.rowWeights = new double[] { 0.0, 0.0, 0.0, 0.0, 0.0, 1.0,
				Double.MIN_VALUE };
		panel.setLayout(gbl_panel);

		panel.setVisible(false);

		JLabel lblType = new JLabel("Type");
		GridBagConstraints gbc_lblType = new GridBagConstraints();
		gbc_lblType.anchor = GridBagConstraints.EAST;
		gbc_lblType.insets = new Insets(0, 0, 5, 5);
		gbc_lblType.gridx = 0;
		gbc_lblType.gridy = 0;
		panel.add(lblType, gbc_lblType);

		GridBagConstraints gbc_typeCombobox = new GridBagConstraints();
		gbc_typeCombobox.insets = new Insets(0, 0, 5, 0);
		gbc_typeCombobox.fill = GridBagConstraints.HORIZONTAL;
		gbc_typeCombobox.gridx = 1;
		gbc_typeCombobox.gridy = 0;
		panel.add(typeCombobox, gbc_typeCombobox);


		JLabel lblTitle = new JLabel("Title");
		GridBagConstraints gbc_lblTitle = new GridBagConstraints();
		gbc_lblTitle.insets = new Insets(0, 0, 5, 5);
		gbc_lblTitle.anchor = GridBagConstraints.WEST;
		gbc_lblTitle.gridx = 0;
		gbc_lblTitle.gridy = 1;
		panel.add(lblTitle, gbc_lblTitle);

		txtTitle = new JTextField();
		txtTitle.setText("title");
		GridBagConstraints gbc_txtTitle = new GridBagConstraints();
		gbc_txtTitle.insets = new Insets(0, 0, 5, 0);
		gbc_txtTitle.fill = GridBagConstraints.HORIZONTAL;
		gbc_txtTitle.gridx = 1;
		gbc_txtTitle.gridy = 1;
		panel.add(txtTitle, gbc_txtTitle);
		txtTitle.setColumns(10);

		JLabel lblHostname = new JLabel("Hostname");
		GridBagConstraints gbc_lblHostname = new GridBagConstraints();
		gbc_lblHostname.anchor = GridBagConstraints.WEST;
		gbc_lblHostname.insets = new Insets(0, 0, 5, 5);
		gbc_lblHostname.gridx = 0;
		gbc_lblHostname.gridy = 2;
		panel.add(lblHostname, gbc_lblHostname);

		txtHostname = new JTextField();
		txtHostname.setText("hostname");
		GridBagConstraints gbc_txtHostname = new GridBagConstraints();
		gbc_txtHostname.insets = new Insets(0, 0, 5, 0);
		gbc_txtHostname.fill = GridBagConstraints.HORIZONTAL;
		gbc_txtHostname.gridx = 1;
		gbc_txtHostname.gridy = 2;
		panel.add(txtHostname, gbc_txtHostname);
		txtHostname.setColumns(10);

		JLabel lblUsername = new JLabel("Username");
		GridBagConstraints gbc_lblUsername = new GridBagConstraints();
		gbc_lblUsername.insets = new Insets(0, 0, 5, 5);
		gbc_lblUsername.anchor = GridBagConstraints.EAST;
		gbc_lblUsername.gridx = 0;
		gbc_lblUsername.gridy = 3;
		panel.add(lblUsername, gbc_lblUsername);

		txtUsername = new JTextField();
		txtUsername.setText("username");
		GridBagConstraints gbc_txtUsername = new GridBagConstraints();
		gbc_txtUsername.insets = new Insets(0, 0, 5, 0);
		gbc_txtUsername.fill = GridBagConstraints.HORIZONTAL;
		gbc_txtUsername.gridx = 1;
		gbc_txtUsername.gridy = 3;
		panel.add(txtUsername, gbc_txtUsername);
		txtUsername.setColumns(10);

		JLabel lblId = new JLabel("ID");
		GridBagConstraints gbc_lblId = new GridBagConstraints();
		gbc_lblId.insets = new Insets(0, 0, 5, 5);
		gbc_lblId.anchor = GridBagConstraints.WEST;
		gbc_lblId.gridx = 0;
		gbc_lblId.gridy = 4;
		panel.add(lblId, gbc_lblId);

		txtId = new JTextField();
		txtId.setEnabled(false);
		txtId.setEditable(false);
		txtId.setText("id");
		GridBagConstraints gbc_txtId = new GridBagConstraints();
		gbc_txtId.insets = new Insets(0, 0, 5, 0);
		gbc_txtId.fill = GridBagConstraints.HORIZONTAL;
		gbc_txtId.gridx = 1;
		gbc_txtId.gridy = 4;
		panel.add(txtId, gbc_txtId);
		txtId.setColumns(10);

		JPanel panel_1 = new JPanel();
		GridBagConstraints gbc_panel_1 = new GridBagConstraints();
		gbc_panel_1.anchor = GridBagConstraints.EAST;
		gbc_panel_1.fill = GridBagConstraints.VERTICAL;
		gbc_panel_1.gridx = 1;
		gbc_panel_1.gridy = 5;
		panel.add(panel_1, gbc_panel_1);

		JButton btnOk = new JButton("OK");
		btnOk.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				panel.setVisible(false);
				dataSource.createOrUpdateConnection(new Connection()
						.setHost(txtHostname.getText())
						.setTitle(txtTitle.getText())
						.setUsername(txtUsername.getText())
						.setId(txtId.getText())
						.setType((Type) typeCombobox.getSelectedItem()));
				clearInput();
			}
		});
		panel_1.add(btnOk);

		JButton btnCancel = new JButton("Cancel");
		btnCancel.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				panel.setVisible(false);
				clearInput();
			}
		});
		panel_1.add(btnCancel);
		edit.addActionListener(new ActionListener() {

			public void actionPerformed(ActionEvent arg0) {
				panel.setVisible(true);
				int selRow = table.getSelectedRow();
				if (selRow < 0) {
					return;
				}
				Connection con = connectionsTableModel.getConnectionAt(selRow);
				// load data
				txtId.setText(con.getId() + "");
				txtHostname.setText(con.getHost());
				txtTitle.setText(con.getTitle());
				txtUsername.setText(con.getUsername());
				typeCombobox.setSelectedItem(con.getType());
			}
		});
		clearInput();
	}

	private void readTypes() {
		this.typeCombobox.removeAllItems();
		
		int selectedIndex = -1;
		for (Type type : typeController.readTypes()) {
			typeCombobox.addItem(type);
			selectedIndex = 0;
		}
		
		this.typeCombobox.setSelectedIndex(selectedIndex);
	}

	private void clearInput() {
		this.txtUsername.setText("");
		this.txtTitle.setText("");
		this.txtHostname.setText("");
		this.txtId.setText("");
	}
	
	@javax.annotation.PostConstruct
	public void init() {
		this.dataHasBeenUpdated();
	}

	public void dataHasBeenUpdated() {
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				connectionsTableModel.refresh(dataSource.readConnections());
				readTypes();
			}
		});
		
	}
}
